
package com.hrt.datasender.datacollect.drive.opc;

import java.util.HashMap;
import java.util.List;

import com.btcode.common.MyLog;
import com.btcode.common.PropertiesUnit;
import com.btcode.log.ILog;

import javafish.clients.opc.JOpc;
import javafish.clients.opc.browser.JOpcBrowser;
import javafish.clients.opc.component.OpcGroup;
import javafish.clients.opc.component.OpcItem;
import javafish.clients.opc.exception.ComponentNotFoundException;
import javafish.clients.opc.exception.ConnectivityException;
import javafish.clients.opc.exception.SynchReadException;
import javafish.clients.opc.exception.SynchWriteException;
import javafish.clients.opc.exception.UnableAddGroupException;
import javafish.clients.opc.exception.UnableAddItemException;
import javafish.clients.opc.variant.Variant;

/**
 * 注册和读取opc变量
 * 
 * @author gislin 2016年2月1日
 */
public class OpcDataClient {

    private String serverProgId = null;
    private String serverClientHandle = null;
    private JOpc jopc;
    private JOpcBrowser jbrowser;
    private String[] allItems = null;
    private OpcGroup group;
    private String groupName;
    private HashMap<String, String> opcData = new HashMap<>();
    private final int updateRate = 200;

    private static ILog log = null;

    /**
     *
     * @param itemNames
     *            opc参数名列表
     * @param groupName
     *            手工分配的唯一组名
     */
    public OpcDataClient(List<String> itemNames, String groupName,String severId,String clientHandle) {
        try {
            if(groupName==null||"".equals(groupName)){
                return;
            }
            if(severId==null||"".equals(severId)){
                return;
            }
            if(clientHandle==null||"".equals(clientHandle)){
                return;
            }
            serverProgId = severId;
            serverClientHandle = clientHandle;

            log = MyLog.getInstance().getLogger(getClass().getName());
            log.info(groupName + "读取中……");

            getJOpc();
            log.info("获取到jopc:" + jopc);
            this.groupName = groupName;
            group = new OpcGroup(groupName, true, updateRate, 0.0f);

            for (String itemName : itemNames) {
                log.info("itemName:" + itemName);
                OpcItem item = new OpcItem(itemName, true, "");
                if (contantItem(itemName)) {
                    group.addItem(item);
                }
                else {
                    log.info(itemName + "，无法读取");
                }
            }
            jopc.addGroup(group);
            jopc.registerGroup(group);
            for (OpcItem opcItem : group.getItems()) {
                jopc.registerItem(group, opcItem);
                log.info(opcItem.getItemName() + "，参数注册成功");
            }

            jopc.synchReadGroup(group);
            log.info(groupName + "读取完毕……");

        }
        catch (ComponentNotFoundException | UnableAddGroupException | UnableAddItemException | SynchReadException e) {
            log.error("opc注册opcitem出错", e);
        }
    }

    public static void initOpc(){
        JOpc.coInitialize();
        JOpcBrowser.coInitialize();
    }


    /**
     * 获取opc对象 gislin 2016年4月1日
     * 
     * @return
     */
    public synchronized JOpc getJOpc() {

        String isReadOpc = PropertiesUnit.getValue("conf", "isReadOpc") + "";
        if ("false".equals(isReadOpc)) {
            return null;
        }

        if (jopc == null) {
            try {
                log.info("serverProgId="+ serverProgId);
                jopc = new JOpc("127.0.0.1", serverProgId, serverClientHandle);
                jopc.connect();
                jbrowser = new JOpcBrowser("127.0.0.1", serverProgId, serverClientHandle);
                jbrowser.connect();
            }
            catch (ConnectivityException e) {
                log.error("opc初始化出错", e);
            }
        }
        return jopc;
    }

    /**
     * 获取这个client读取的数据 gislin 2016年4月1日
     * 
     * @return
     */
    public HashMap<String, String> getData() {
        if(serverProgId==null){
            return new HashMap<>();
        }
        getJOpc();

        OpcGroup responseGroup;
        try {
            responseGroup = jopc.synchReadGroup(group);
            OpcItem[] items = responseGroup.getItemsAsArray();

            for (OpcItem item : items) {
                String itemName = item.getItemName();
                String value = item.getValue().getString();
                opcData.put(itemName, value);
                log.info(itemName+"="+value);
            }

        }
        catch (ComponentNotFoundException | SynchReadException e) {
            log.error("读取数据出错", e);
        }

        return opcData;
    }

    /**
     * 判断服务是否包含参数 gislin 2016年2月22日
     * 
     * @param name
     * @return
     */
    public synchronized boolean contantItem(String name) {
        return true;

//        name = name.replaceAll(".PV", "");
//        if (allItems == null) {
//            try {
//                allItems = jbrowser.getOpcBranch("");
//                for(String branch:allItems){
//                    log.info("opcBranch:" + branch);
//                    if("_System".equals(branch)){
//                        continue;
//                    }
//                    String[] secBranchs = jbrowser.getOpcBranch(branch);
//                    for(String secBranch:secBranchs){
//                        log.info("secBranch:" + secBranch);
//                    }
////                        String[] items = jbrowser.getOpcItems("ETH_01.PLC1",true);
////                        for(String item:items){
////                            log.info("item:" + item);
////                        }
//
//                }
//                log.info("opcBranch参数个数：" + allItems.length);
//            }
//            catch (UnableBrowseBranchException | UnableIBrowseException e) {
//                log.error("获取所有参数出错", e);
//                e.printStackTrace();
//            }
//        }
//
//        if(allItems != null) {
//            for (String itemName : allItems) {
//                if (itemName.equals(name)) {
//                    return true;
//                }
//            }
//        }

//        return false;
    }

    public String getGroupName() {
        return groupName;
    }

    public void setGroupName(String groupName) {
        this.groupName = groupName;
    }

    /**
     * 写opc值 gislin 2016年3月4日
     * 
     * @param opcName
     * @param value
     * @param qn
     * @return
     * @throws ComponentNotFoundException
     * @throws SynchWriteException
     */
    public boolean writeOpcItem(String opcName, String value, String qn)
            throws ComponentNotFoundException, SynchWriteException {
        try {
            getJOpc();
            OpcItem[] items = group.getItemsAsArray();
            OpcItem opcitem = null;

            for (OpcItem item : items) {
                if (item.getItemName().equals(opcName)) {
                    opcitem = item;
                    break;
                }
            }

            Variant opcValue = new Variant(value);
            if(opcitem!=null) {
                opcitem.setValue(opcValue); 
                jopc.synchWriteItem(group, opcitem);
            }
            return true;
        }
        catch (Exception e) {
            log.error("写入opc点值出错", e);
            return false;
        }
    }

}
